package com.zxl.working.utils;

import com.zxl.working.entity.ErrorMsg;
import com.zxl.working.entity.backend.ProvideDetail;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.*;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Component
public class FileUitl {
    private Logger logger = LogManager.getLogger(FileUitl.class);
    private static final String XLS = "xls";
    private static final String XLSX = "xlsx";

    private Workbook getWorkBook(InputStream inputStream,String fileType) throws Exception{
        Workbook workbook = null;
        if (fileType.equalsIgnoreCase(XLS)) {
            workbook = new HSSFWorkbook(inputStream);
        } else if (fileType.equalsIgnoreCase(XLSX)) {
            workbook = new XSSFWorkbook(inputStream);
        }
        return workbook;
    }

    public List<ProvideDetail> readExcel(String fileName){
        Workbook workbook = null;
        FileInputStream inputStream = null;

        try {
            // 获取Excel后缀名
            String fileType = fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length());
            // 获取Excel文件
            File excelFile = new File(fileName);
            if (!excelFile.exists()) {
                logger.warn("指定的Excel文件不存在！");
                return null;
            }

            // 获取Excel工作簿
            inputStream = new FileInputStream(excelFile);
            workbook = getWorkBook(inputStream, fileType);

            // 读取excel中的数据
            List<ProvideDetail> resultDataList = parseExcel(workbook);

            return resultDataList;
        } catch (Exception e) {
            logger.warn("解析Excel失败，文件名：" + fileName + " 错误信息：" + e.getMessage());
            e.printStackTrace();
            return null;
        } finally {
            try {
                if (null != workbook) {
                    workbook.close();
                }
                if (null != inputStream) {
                    inputStream.close();
                }
            } catch (Exception e) {
                logger.warn("关闭数据流出错！错误信息：" + e.getMessage());
                e.printStackTrace();
                return null;
            }
        }
    }

    private List<ProvideDetail> parseExcel(Workbook workbook) {
        List<ProvideDetail> resultDataList = new ArrayList<>();
        // 解析sheet
        for (int sheetNum = 0; sheetNum < workbook.getNumberOfSheets(); sheetNum++) {
            Sheet sheet = workbook.getSheetAt(sheetNum);

            // 校验sheet是否合法
            if (sheet == null) {
                continue;
            }

            // 获取第一行数据
            int firstRowNum = sheet.getFirstRowNum();
            Row firstRow = sheet.getRow(firstRowNum);
            if (null == firstRow) {
                logger.warn("解析Excel失败，在第一行没有读取到任何数据！");
            }

            // 解析每一行的数据，构造数据对象
            int rowStart = firstRowNum + 1;
            int rowEnd = sheet.getPhysicalNumberOfRows();
            for (int rowNum = rowStart; rowNum < rowEnd; rowNum++) {
                Row row = sheet.getRow(rowNum);

                if (null == row) {
                    continue;
                }

                ProvideDetail resultData = convertRowToData(row);
                if (null == resultData) {
                    break;
                }
                resultDataList.add(resultData);
            }
        }

        return resultDataList;
    }

    /**
     * 将单元格内容转换为字符串
     * @param cell
     * @return
     */
    private static String convertCellValueToString(Cell cell) {
        if(cell==null){
            return null;
        }
        cell.setCellType(CellType.STRING);
        String returnValue = null;
        switch (cell.getCellType()) {
            case NUMERIC:   //数字
                /*Double doubleValue = cell.getNumericCellValue();

                // 格式化科学计数法，取一位整数
                DecimalFormat df = new DecimalFormat("0");
                returnValue = df.format(doubleValue);*/
                returnValue = cell.getStringCellValue();
                break;
            case STRING:    //字符串
                returnValue = cell.getStringCellValue();
                break;
            case BOOLEAN:   //布尔
                Boolean booleanValue = cell.getBooleanCellValue();
                returnValue = booleanValue.toString();
                break;
            case BLANK:     // 空值
                break;
            case FORMULA:   // 公式
                returnValue = cell.getCellFormula();
                break;
            case ERROR:     // 故障
                break;
            default:
                break;
        }
        return returnValue;
    }

    /**
     * 提取每一行中需要的数据，构造成为一个结果数据对象
     *
     * 当该行中有单元格的数据为空或不合法时，忽略该行的数据
     *
     * @param row 行数据
     * @return 解析后的行数据对象，行数据错误时返回null
     */
    private static ProvideDetail convertRowToData(Row row) {
        ProvideDetail resultData = new ProvideDetail();

        Cell cell;
        int cellNum = 0;
        // 获取姓名
        cell = row.getCell(cellNum++);
        String name = convertCellValueToString(cell);
        resultData.setPayeeName(name!=null?name.trim():name);
        // 获取开户行
        cell = row.getCell(cellNum++);
        String bankName = convertCellValueToString(cell);
        resultData.setPayeeAccountBankName(bankName!=null?bankName.trim():bankName);
        // 获取证件号
        cell = row.getCell(cellNum++);
        String cardCode = convertCellValueToString(cell);
        resultData.setCardCode(cardCode!=null?cardCode.trim():cardCode);
        // 获取银行账号
        cell = row.getCell(cellNum++);
        String account = convertCellValueToString(cell);
        resultData.setPayeeAccount(account!=null?account.trim():account);
        // 获取交易金额
        cell = row.getCell(cellNum++);
        String money = convertCellValueToString(cell);
        if(money==null || money.trim().equals("")){
            money="0";
        }
        resultData.setPayAmount(Double.parseDouble(money.trim()));
        // 获取手机号
        cell = row.getCell(cellNum++);
        String mobile = convertCellValueToString(cell);
        resultData.setPayeeMobile(mobile!=null?mobile.trim():mobile);
        // 获取备注
        cell = row.getCell(cellNum++);
        String remark = convertCellValueToString(cell);
        resultData.setPayeeRemark(remark!=null?remark.trim():remark);
        //获取项目名称
        cell = row.getCell(cellNum++);
        String title = convertCellValueToString(cell);
        resultData.setTitle(title!=null?title.trim():title);
        //获取项目描述
        cell = row.getCell(cellNum++);
        String info = convertCellValueToString(cell);
        resultData.setInfo(info!=null?info.trim():info);
        //获取项目负责人名称
        cell = row.getCell(cellNum++);
        String u_name = convertCellValueToString(cell);
        resultData.setName(u_name!=null?u_name.trim():u_name);
        //获取负责人电话
        cell = row.getCell(cellNum++);
        String phone = convertCellValueToString(cell);
        resultData.setPhone(phone!=null?phone.trim():phone);

        if((resultData.getCardCode()==null || resultData.getCardCode().equals(""))
                && ( resultData.getPayeeName()==null || resultData.getPayeeName().equals(""))){
            return null;
        }
        return resultData;
    }

    /**
     * 导出excel
     * @param headerName （excel列名称）
     * @param headerKey （导出对象属性名）
     * @param sheetName （excel 页签名称）
     * @param dataList （导出的数据）
     * @return
     */
    public XSSFWorkbook createExcel(List<ErrorMsg> errorList,String[] headerName, String[] headerKey, String sheetName, List dataList) {
        try {
            if (headerKey.length <= 0) {
                return null;
            }
            if (dataList.size() <= 0) {
                return null;
            }
            XSSFWorkbook wb = new XSSFWorkbook();
            XSSFSheet sheet;
            if ((sheetName == null) || (sheetName.equals("")))
                sheet = wb.createSheet("Sheet1");
            else {
                sheet = wb.createSheet(sheetName);
            }
            XSSFRow row = sheet.createRow(0);
            XSSFCellStyle style = wb.createCellStyle();
            XSSFDataFormat format = wb.createDataFormat();
            style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            style.setFillForegroundColor(IndexedColors.RED.index);
            style.setDataFormat(format.getFormat("@"));
            XSSFCell cell = null;
            if (headerName.length > 0) {
                for (int i = 0; i < headerName.length; i++) {
                    cell = row.createCell(i);
                    cell.setCellValue(headerName[i]);
                }
            }
            int n = 0;

            XSSFCell cell0 = null;
            XSSFCell cell1 = null;

            for (Iterator localIterator = dataList.iterator(); localIterator.hasNext();) {
                Object obj = localIterator.next();
                Field[] fields = obj.getClass().getDeclaredFields();
                row = sheet.createRow(n + 1);
                int index=-1;
                boolean isRed = false;
                for (int j = 0; j < headerKey.length; j++) {
                    if (headerName.length <= 0) {
                        cell0 = row.createCell(j);
                        cell0.setCellValue(headerKey[j]);

                    }
                    for (int i = 0; i < fields.length; i++) {
                        if (fields[i].getName().equals(headerKey[j])) {
                            fields[i].setAccessible(true);
                            if("status".equals(fields[i].getName())){
                                /*if(!"1".equals(fields[i].get(obj).toString())){
                                    isRed = true;
                                    index=Integer.parseInt(fields[i].get(obj).toString());
                                }
                                break;*/
                            }else {
                                cell1 = row.createCell(j-1);
                                cell1.setCellValue(ObjectUtils.isEmpty(fields[i].get(obj)) ? "" : fields[i].get(obj).toString());
                            }
                           /* if(isRed && index+1==j){
                                cell1.setCellStyle(style);
                            }*/
                            if (fields[i].get(obj) == null) {
                                cell1.setCellValue("");
                                break;
                            }
//                            if ((fields[i].get(obj) instanceof Number)) {
//                                cell1.setCellType(CellType.NUMERIC);
//                                cell1.setCellValue(Double.parseDouble(fields[i].get(obj).toString()));
//                                break;
//                            }
                            if ("".equals(fields[i].get(obj))) {
                                cell1.setCellValue("");
                                cell1.setCellType(CellType.BLANK);
                                break;
                            }

                            break;
                        }
                    }
                }
                n++;
            }

            if(errorList!=null && errorList.size()>0){
                for (ErrorMsg e:errorList){
                    try {
                        //加批注
                        XSSFDrawing draw = sheet.createDrawingPatriarch();
                        XSSFComment comment = draw.createCellComment(new XSSFClientAnchor(0, 0, 0, 0, 4, 2, 9, 7));
                        XSSFRichTextString rtf = new XSSFRichTextString(e.getMsg());
                        XSSFFont commentFormatter = wb.createFont();
                        commentFormatter.setFontName("宋体");
                        //设置字体大小
                        commentFormatter.setFontHeightInPoints((short) 9);
                        rtf.applyFont(commentFormatter);
                        comment.setString(rtf);
                        comment.setAuthor("Zhihui Li");
                        // 将批注添加到单元格对象中
                        sheet.getRow(e.getRow()).getCell(e.getCol()).setCellComment(comment);
                        sheet.getRow(e.getRow()).getCell(e.getCol()).setCellStyle(style);
                    }catch (Exception ex){
                        ex.printStackTrace();
                    }

                }
            }


            for (int i = 0; i < headerKey.length; i++) {
                sheet.setColumnWidth(i, headerKey[i].getBytes().length*2*256);
            }
            XSSFWorkbook localHSSFWorkbook1 = wb;
            return localHSSFWorkbook1;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
        }
    }
}
